<?php
/**
 * 简单KaTeX处理类
 * 替代 katex/katex-php 包的功能
 */

namespace app\common\library;

class SimpleKaTeX
{
    /**
     * 处理数学公式
     * @param string $content 包含数学公式的内容
     * @return string 处理后的内容
     */
    public static function processFormulas($content)
    {
        // 先保护已有的HTML标签避免重复处理
        $protectedHtml = [];
        $placeholder = '___HTML_PROTECTED___';
        $counter = 0;
        
        // 保护已存在的数学公式HTML（避免重复处理）
        $content = preg_replace_callback('/<(?:div|span)[^>]*class="[^"]*math-formula[^"]*"[^>]*>.*?<\/(?:div|span)>/s', function($matches) use (&$protectedHtml, $placeholder, &$counter) {
            $key = $placeholder . $counter++;
            $protectedHtml[$key] = $matches[0];
            return $key;
        }, $content);
        
        // 处理 \[...\] 块级公式
        $content = preg_replace_callback('/\\\\\[(.*?)\\\\\]/s', function($matches) {
            $latex = trim($matches[1]);
            return '<div class="math-formula block-formula" style="text-align: center; margin: 1em 0; font-size: 1.1em; font-family: \'Times New Roman\', serif;">' . self::convertLatexToHtml($latex) . '</div>';
        }, $content);
        
        // 处理 \(...\) 行内公式
        $content = preg_replace_callback('/\\\\\((.*?)\\\\\)/s', function($matches) {
            $latex = trim($matches[1]);
            return '<span class="math-formula inline-formula" style="font-style: italic; font-family: \'Times New Roman\', serif;">' . self::convertLatexToHtml($latex) . '</span>';
        }, $content);
        
        // 处理$$...$$块级公式
        $content = preg_replace_callback('/\$\$(.*?)\$\$/s', function($matches) {
            $latex = trim($matches[1]);
            return '<div class="math-formula block-formula" style="text-align: center; margin: 1em 0; font-size: 1.1em; font-family: \'Times New Roman\', serif;">' . self::convertLatexToHtml($latex) . '</div>';
        }, $content);
        
        // 处理$...$行内公式（更精确的匹配）
        $content = preg_replace_callback('/\$([^\$\n\r]+?)\$/', function($matches) {
            $content = trim($matches[1]);
            if (self::isLikelyMathFormula($content)) {
                return '<span class="math-formula inline-formula" style="font-style: italic; font-family: \'Times New Roman\', serif;">' . self::convertLatexToHtml($content) . '</span>';
            }
            return '$' . $matches[1] . '$'; // 不是数学公式，保持原样
        }, $content);
        
        // 处理独立的LaTeX公式（无数学环境包裹）
        
        // 1. 处理包含\text和\frac的复杂公式行
        $content = preg_replace_callback('/\\\\text\{[^}]+\}[^\n]*?\\\\frac\{[^}]+\}\{[^}]+\}[^\n]*/', function($matches) {
            return '<span class="math-formula inline-formula" style="font-style: italic; font-family: \'Times New Roman\', serif;">' . self::convertLatexToHtml($matches[0]) . '</span>';
        }, $content);
        
        // 2. 处理独立的分数公式（关键修复）
        $content = preg_replace_callback('/\\\\frac\{[^}]+\}\{[^}]+\}/', function($matches) {
            return '<span class="math-formula inline-formula" style="font-style: italic; font-family: \'Times New Roman\', serif;">' . self::convertLatexToHtml($matches[0]) . '</span>';
        }, $content);
        
        // 3. 处理独立的文本命令（关键修复）
        $content = preg_replace_callback('/\\\\text\{[^}]+\}/', function($matches) {
            return '<span class="math-formula inline-formula" style="font-style: italic; font-family: \'Times New Roman\', serif;">' . self::convertLatexToHtml($matches[0]) . '</span>';
        }, $content);
        
        // 4. 处理数学符号（\times, \approx等）
        $content = preg_replace_callback('/\\\\(times|div|pm|leq|geq|neq|approx)/', function($matches) {
            return '<span class="math-formula inline-formula" style="font-style: italic; font-family: \'Times New Roman\', serif;">' . self::convertLatexToHtml('\\' . $matches[1]) . '</span>';
        }, $content);
        
        // 还原保护的HTML
        foreach ($protectedHtml as $key => $html) {
            $content = str_replace($key, $html, $content);
        }
        
        return $content;
    }
    
    /**
     * 判断文本是否像数学公式
     * @param string $content 文本内容
     * @return bool
     */
    private static function isLikelyMathFormula($content)
    {
        // 包含常见数学符号或LaTeX命令的被认为是数学公式
        $mathIndicators = [
            '\\frac', '\\sqrt', '\\sum', '\\int', '\\prod', '\\lim',
            '\\alpha', '\\beta', '\\gamma', '\\delta', '\\pi', '\\theta',
            '\\times', '\\div', '\\cdot', '\\pm', '\\leq', '\\geq',
            '\\neq', '\\approx', '\\infty', '\\partial', '\\nabla',
            '^{', '_{', '\\{', '\\}', '\\text{', '\\mathbf{',
            '+', '-', '=', '<', '>', '≤', '≥', '≠', '≈', '×', '÷',
            '/', '\\over'
        ];
        
        foreach ($mathIndicators as $indicator) {
            if (strpos($content, $indicator) !== false) {
                return true;
            }
        }
        
        // 检查是否包含数字和运算符的组合
        if (preg_match('/\d+[+\-*\/=^()]+/', $content)) {
            return true;
        }
        
        return false;
    }
    
    /**
     * 将LaTeX公式转换为HTML格式
     * @param string $content LaTeX内容
     * @return string HTML格式的数学公式
     */
    private static function convertLatexToHtml($content)
    {
        $content = trim($content);
        
        // 1. 处理换行符号
        $content = str_replace('\\\\', '<br>', $content);
        $content = str_replace('\\n', '<br>', $content);
        
        // 2. 处理对齐符号 &
        $content = str_replace('&', '', $content);
        
        // 3. 处理文本命令 \text{}（在其他处理之前）
        $content = preg_replace_callback('/\\\\text\s*\{([^}]+)\}/', function($matches) {
            return '<span style="font-style: normal; font-family: serif;">' . htmlspecialchars($matches[1], ENT_QUOTES, 'UTF-8') . '</span>';
        }, $content);
        
        // 4. 处理分数 \frac{分子}{分母}
        $content = preg_replace_callback('/\\\\frac\s*\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}\s*\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/', function($matches) {
            $numerator = self::convertLatexToHtml($matches[1]);
            $denominator = self::convertLatexToHtml($matches[2]);
            return '<span class="fraction" style="display: inline-block; text-align: center; vertical-align: middle; margin: 0 0.1em;">' .
                   '<span style="display: block; border-bottom: 1px solid #000; padding: 0.1em 0.2em; line-height: 1;">' . $numerator . '</span>' .
                   '<span style="display: block; padding: 0.1em 0.2em; line-height: 1;">' . $denominator . '</span>' .
                   '</span>';
        }, $content);
        
        // 5. 处理根号 \sqrt{内容}
        $content = preg_replace_callback('/\\\\sqrt\s*\{([^}]+)\}/', function($matches) {
            $inner = self::convertLatexToHtml($matches[1]);
            return '<span class="sqrt" style="position: relative; padding-left: 0.3em;">√<span style="border-top: 1px solid #000; padding: 0 0.1em;">' . $inner . '</span></span>';
        }, $content);
        
        // 6. 处理上标 ^{内容}
        $content = preg_replace_callback('/\^\s*\{([^}]+)\}/', function($matches) {
            return '<sup style="font-size: 0.75em; line-height: 0;">' . self::convertLatexToHtml($matches[1]) . '</sup>';
        }, $content);
        
        // 7. 处理下标 _{内容}
        $content = preg_replace_callback('/_\s*\{([^}]+)\}/', function($matches) {
            return '<sub style="font-size: 0.75em; line-height: 0;">' . self::convertLatexToHtml($matches[1]) . '</sub>';
        }, $content);
        
        // 8. 处理简单上标 ^字符
        $content = preg_replace('/\^([a-zA-Z0-9])/', '<sup style="font-size: 0.75em; line-height: 0;">$1</sup>', $content);
        
        // 9. 处理简单下标 _字符
        $content = preg_replace('/_([a-zA-Z0-9])/', '<sub style="font-size: 0.75em; line-height: 0;">$1</sub>', $content);
        
        // 10. 处理希腊字母和数学符号
        $content = self::processSymbols($content);
        
        // 11. 处理百分号（保持原样）
        $content = preg_replace('/(\d+(?:\.\d+)?)\\%/', '$1%', $content);
        $content = preg_replace('/(\d+(?:\.\d+)?)%/', '$1%', $content);
        
        // 12. 清理多余的反斜杠
        $content = preg_replace('/\\\\([{}])/', '$1', $content);
        
        return $content;
    }
    
    /**
     * 处理数学符号和希腊字母
     * @param string $content 内容
     * @return string 处理后的内容
     */
    private static function processSymbols($content)
    {
        // 希腊字母映射
        $greekLetters = [
            '\\\\alpha\\b' => 'α', '\\\\beta\\b' => 'β', '\\\\gamma\\b' => 'γ', '\\\\delta\\b' => 'δ',
            '\\\\epsilon\\b' => 'ε', '\\\\zeta\\b' => 'ζ', '\\\\eta\\b' => 'η', '\\\\theta\\b' => 'θ',
            '\\\\iota\\b' => 'ι', '\\\\kappa\\b' => 'κ', '\\\\lambda\\b' => 'λ', '\\\\mu\\b' => 'μ',
            '\\\\nu\\b' => 'ν', '\\\\xi\\b' => 'ξ', '\\\\pi\\b' => 'π', '\\\\rho\\b' => 'ρ',
            '\\\\sigma\\b' => 'σ', '\\\\tau\\b' => 'τ', '\\\\upsilon\\b' => 'υ', '\\\\phi\\b' => 'φ',
            '\\\\chi\\b' => 'χ', '\\\\psi\\b' => 'ψ', '\\\\omega\\b' => 'ω',
            // 大写希腊字母
            '\\\\Gamma\\b' => 'Γ', '\\\\Delta\\b' => 'Δ', '\\\\Theta\\b' => 'Θ', '\\\\Lambda\\b' => 'Λ',
            '\\\\Xi\\b' => 'Ξ', '\\\\Pi\\b' => 'Π', '\\\\Sigma\\b' => 'Σ', '\\\\Phi\\b' => 'Φ',
            '\\\\Psi\\b' => 'Ψ', '\\\\Omega\\b' => 'Ω'
        ];
        
        // 数学符号映射
        $mathSymbols = [
            '\\\\times\\b' => '×', '\\\\div\\b' => '÷', '\\\\pm\\b' => '±', '\\\\mp\\b' => '∓',
            '\\\\cdot\\b' => '⋅', '\\\\ast\\b' => '∗', '\\\\star\\b' => '⋆',
            '\\\\leq\\b' => '≤', '\\\\geq\\b' => '≥', '\\\\neq\\b' => '≠', '\\\\approx\\b' => '≈',
            '\\\\equiv\\b' => '≡', '\\\\sim\\b' => '∼', '\\\\propto\\b' => '∝',
            '\\\\infty\\b' => '∞', '\\\\partial\\b' => '∂', '\\\\nabla\\b' => '∇',
            '\\\\sum\\b' => '∑', '\\\\int\\b' => '∫', '\\\\prod\\b' => '∏',
            '\\\\in\\b' => '∈', '\\\\notin\\b' => '∉', '\\\\subset\\b' => '⊂', '\\\\supset\\b' => '⊃',
            '\\\\cup\\b' => '∪', '\\\\cap\\b' => '∩', '\\\\emptyset\\b' => '∅',
            '\\\\rightarrow\\b' => '→', '\\\\leftarrow\\b' => '←', '\\\\leftrightarrow\\b' => '↔',
            '\\\\Rightarrow\\b' => '⇒', '\\\\Leftarrow\\b' => '⇐', '\\\\Leftrightarrow\\b' => '⇔'
        ];
        
        // 函数名称处理 - 保持正体
        $functions = [
            '\\\\sin\\b' => '<span style="font-style: normal;">sin</span>',
            '\\\\cos\\b' => '<span style="font-style: normal;">cos</span>',
            '\\\\tan\\b' => '<span style="font-style: normal;">tan</span>',
            '\\\\log\\b' => '<span style="font-style: normal;">log</span>',
            '\\\\ln\\b' => '<span style="font-style: normal;">ln</span>',
            '\\\\exp\\b' => '<span style="font-style: normal;">exp</span>',
            '\\\\max\\b' => '<span style="font-style: normal;">max</span>',
            '\\\\min\\b' => '<span style="font-style: normal;">min</span>',
            '\\\\lim\\b' => '<span style="font-style: normal;">lim</span>'
        ];
        
        // 应用所有替换
        $allReplacements = array_merge($greekLetters, $mathSymbols);
        foreach ($allReplacements as $latex => $html) {
            $content = preg_replace('/' . $latex . '/', $html, $content);
        }
        
        // 单独处理函数名（避免HTML标签冲突）
        foreach ($functions as $latex => $html) {
            $content = preg_replace('/' . $latex . '/', $html, $content);
        }
        
        return $content;
    }
    
    /**
     * 生成KaTeX CSS类
     * @return string CSS样式
     */
    public static function generateCSS()
    {
        return '
        <style>
        .math-formula {
            font-family: "Times New Roman", serif;
        }
        .block-formula {
            display: block;
            text-align: center;
            margin: 1em 0;
            font-size: 1.1em;
        }
        .inline-formula {
            display: inline;
            font-style: italic;
        }
        .fraction {
            display: inline-block;
            text-align: center;
            vertical-align: middle;
            margin: 0 0.1em;
        }
        .sqrt {
            position: relative;
            padding-left: 0.3em;
        }
        </style>';
    }
    
    /**
     * 生成KaTeX JavaScript处理代码
     * @return string JavaScript代码
     */
    public static function generateJS()
    {
        return '
        <script>
        // 简单的数学公式处理脚本
        document.addEventListener("DOMContentLoaded", function() {
            // 处理行内公式
            var inlineMathElements = document.querySelectorAll(".math-formula.inline-formula");
            inlineMathElements.forEach(function(element) {
                // 这里可以添加实际的渲染逻辑
                console.log("Inline math formula processed");
            });
            
            // 处理块级公式
            var blockMathElements = document.querySelectorAll(".math-formula.block-formula");
            blockMathElements.forEach(function(element) {
                // 这里可以添加实际的渲染逻辑
                console.log("Block math formula processed");
            });
        });
        </script>';
    }
}